package com.sanri.tools.modules.page.service;

import com.alibaba.fastjson.JSON;
import com.sanri.tools.modules.core.service.cc.CommonConfigService;
import com.sanri.tools.modules.core.service.connect.ConnectService;
import com.sanri.tools.modules.page.service.dto.LoadDataParam;
import com.sanri.tools.modules.page.service.dto.pageconfig.PageComponent;
import com.sanri.tools.modules.page.service.dto.pageconfig.PageConfig;
import com.sanri.tools.modules.proxy.service.HttpFileManager;
import com.sanri.tools.modules.proxy.service.dtos.RequestInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.message.BasicStatusLine;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import javax.activation.DataHandler;
import javax.script.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import static org.apache.http.HttpVersion.HTTP_1_1;

@Service
@Slf4j
public class ComponentService {
    @Autowired
    private PageManager pageManager;
    @Autowired
    private HttpFileManager httpFileManager;

    private ScriptEngineManager manager = new ScriptEngineManager();

    @Autowired
    private CommonConfigService commonConfigService;

    /**
     * 模块动态数据加载
     * @param loadDataParam
     */
    public void loadData(LoadDataParam loadDataParam, HttpServletResponse response) throws IOException {
        PageConfig pageConfig = pageManager.loadPageConfig(loadDataParam.getPageName());
        List<PageComponent> pageComponents = pageConfig.getPageComponents();
        Map<String, PageComponent> pageComponentMap = pageComponents.stream().collect(Collectors.toMap(PageComponent::getName, Function.identity()));
        PageComponent pageComponent = pageComponentMap.get(loadDataParam.getComponentName());
        String data = pageComponent.getData();
        String[] split = StringUtils.split(data, "|");

        switch (split[0]){
            case "static":
                break;
            case "httpConfig":
                String[] request = StringUtils.split(split[1], "&");

                CloseableHttpResponse closeableHttpResponse = httpFileManager.sendRequest(request[0], request[1], loadDataParam.getParams());

                Header firstHeader = closeableHttpResponse.getFirstHeader("Content-Type");

                if (StringUtils.isNotBlank(pageComponent.getDataHandler())) {
                    // 理论上要根据 content-type 来处理接口数据, 目前暂时默认都是 json 数据
                    try {
                        HttpEntity entity = closeableHttpResponse.getEntity();
                        String content = EntityUtils.toString(entity);
                        // 查询对应处理函数, 对内容进行处理, datahandler 是一段 js 脚本
                        String dataHandler = pageComponent.getDataHandler();

                        // 引擎上下文
                        ScriptEngine engine = manager.getEngineByName("js");

                        // 读取 dataHandler 相关处理脚本; 脚本关系靠前后顺序
                        String[] handlers = StringUtils.split(dataHandler, "&");
                        for (String handler : handlers) {
                            String loadContent = commonConfigService.readTemplateFileContent("datahandler.js", handler);
                            engine.eval(loadContent);
                        }

                        // 最后执行 main 函数处理数据
                        Invocable invocable = (Invocable) engine;
//                        SimpleBindings simpleBindings = new SimpleBindings();
//                        simpleBindings.put("content",content);
                        Object res = invocable.invokeFunction("main",content);

                        if (res instanceof String) {
                            response.getWriter().write((String)res);
                        }else {
                            response.setHeader("Content-Type","application/json");
                            response.getWriter().write(JSON.toJSONString(res));
                        }
                    } catch (ScriptException | NoSuchMethodException e ) {
//                        e.printStackTrace();
                        response.getWriter().write(e.getMessage());
                    } finally {
                        closeableHttpResponse.close();
                    }

                }else {
                    try {
                        HttpEntity entity = closeableHttpResponse.getEntity();
                        String content = EntityUtils.toString(entity);
                        response.getWriter().write(content);
                    }finally {
                        closeableHttpResponse.close();
                    }
                }

                break;
            default:
                break;
        }
    }
}
